package com.zndroid.logcat.core;

import androidx.annotation.NonNull;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by lzy on 2021/1/15.
 * mapper logcat by process
 */
public final class LogcatMapper implements Runnable {
    private final IMapper mapper;
    private final AtomicBoolean isReading = new AtomicBoolean(false);

    public interface IMapper {
        /**
         * call back for log info
         * @param info log info
         * */
        void onConsole(LogInfo info);
    }

    public LogcatMapper(@NonNull IMapper mapper) {
        this.mapper = mapper;
    }

    public void setReading(boolean isReading) {
        this.isReading.set(isReading);
    }

    @Override
    public void run() {
        BufferedReader reader = null;
        try {
            Process process = new ProcessBuilder("logcat", "-v", "threadtime").start();
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while (isReading.get() && (line = reader.readLine()) != null) {
                synchronized (LogcatMapper.class) {
                    if (LogInfo.IGNORED_LOG.contains(line)) {
                        continue;
                    }

                    LogInfo info = LogInfo.create(line);
                    if (info != null) {
                        mapper.onConsole(info);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(reader);
        }
    }

    public void clean() {
        try {
            new ProcessBuilder("logcat", "-c").start();
        } catch (IOException ignored) {
            //ignore
        }
    }

    private void close(Closeable...closes){
        for(Closeable close : closes){
            if(null!=close){
                try{
                    close.close();
                }catch (IOException ignored){
                    //ignore
                }
            }
        }
    }
}
